package com.zyc.remoting.transport.netty.coder;

import com.zyc.serialize.Serializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * @author zyc
 * @create 2022-06-04-16:18
 */
public class NettyRpcDecoder extends ByteToMessageDecoder {
    private final Serializer serializer;
    private final Class<?> genericClass;

    /**
     * 防止粘包定义的长度信息存储在头部 4 个字节的int
     */
    private static final int BODY_LENGTH = 4;

    public NettyRpcDecoder(Serializer serializer, Class<?> genericClass) {
        this.serializer = serializer;
        this.genericClass = genericClass;
    }

    /**
     * 解码 ByteBuf
     * @param channelHandlerContext 解码器关联的上下文
     * @param byteBuf 入站数据
     * @param list 解码后的数据存放位置
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        if (byteBuf.readableBytes() >= BODY_LENGTH) {
            byteBuf.markReaderIndex();
            int dataLength = byteBuf.readInt();

            if (dataLength < 0 || byteBuf.readableBytes() < 0) {
                System.out.println("非法数据长度");
            }

            if (byteBuf.readableBytes() < dataLength) {
                byteBuf.resetReaderIndex();
                return;
            }

            byte[] body = new byte[dataLength];
            byteBuf.readBytes(body);
            Object obj = serializer.deserialize(body, genericClass);
            list.add(obj);
        }
    }
}
